/*
 * Copyright 2016-2019 NXP
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * o Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * o Redistributions in binary form must reproduce the above copyright notice, this
 *   list of conditions and the following disclaimer in the documentation and/or
 *   other materials provided with the distribution.
 *
 * o Neither the name of NXP Semiconductor, Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
/**
 * @file    LPC55S69_Project.c
 * @brief   Application entry point.
 */
#include <stdio.h>
#include <tarm_ctimer.h>
#include <tarm_CTIMER_PWM.h>
#include "board.h"
#include "peripherals.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "LPC55S69_cm33_core0.h"
#include "fsl_debug_console.h"
/* TODO: insert other include files here. */
#include "tarm_iic.h"
#include "tarm_exit.h"
#include "tarm_uart.h"
#include <tarm_CTIMER_PWM.h>
#include "tarm_math.h"

#include "hardware/tarm_io.h"
#include "hardware/tarm_limit.h"
#include "hardware/tarm_time.h"
#include "hardware/tarm_communication.h"
#include "hardware/closeloop/closeloop.h"

#include "application/tarm_run.h"
#include "application/tarm_init.h"
#include "application/tarm_command.h"

#include "stdlib.h"
#include "my_sys.h"

/* TODO: insert other definitions and declarations here. */
void MainInit(void);
void ReportStruct_Handle(void);

/*
 * @brief   Application entry point.
 */
int main(void) {

  	/* Init board hardware. */
    BOARD_InitBootPins();
    BOARD_InitBootClocks();
    BOARD_InitBootPeripherals();
  	/* Init FSL debug console. */
    BOARD_InitDebugConsole();

    /* Print a note to terminal. */
    PRINTF("\r\n GPIO Driver example\r\n");
    PRINTF("\r\n The LED is blinking.\r\n");
    LED_BLUE_OFF();
    LED_GREEN_OFF();

    /* Force the counter to be placed into memory. */
    USART_EnableInterrupts(USART_FL0_PERIPHERAL, kUSART_RxLevelInterruptEnable);
    /* Enable interrupt FLEXCOMM0_IRQn request in the NVIC */
    EnableIRQ(USART_FL0_FLEXCOMM_IRQN);

    SysTick_Config(SystemCoreClock / 1000U);

    MainInit();

    /* Enter an infinite loop, just incrementing a counter. */
    while(1) {
//        i++ ;
//        LED_RED_TOGGLE();
        SysTick_DelayTicks(100);

        uart_tips();
        uart2_tips();

        ReportStruct_Handle();
        /* 'Dummy' NOP to allow source level single stepping of
            tight while() loop */
        __asm volatile ("nop");
    }
    return 0 ;
}

void MainInit(void)
{
	tarm_initMathAcce();
	//��ʼ����ʼ
	SteeringIO_Init();
	LimitIO_Init();

//	Uart0_Init();
	PRINTF_UART0("\r\nUART is initial, welcome to TARM V1.1\r\n");
//	Uart1_Init();
	PRINTF_UART1("\r\nUART is initial, welcome to TARM V1.1\r\n");

	TimeBase_InitUnstart();
	TimePV_InitUnstart(1000);
	PRINTF_UART0("\r\ntime base/pv enable\r\n");
	PRINTF_UART1("\r\ntime base/pv disable\r\n");

	//�����ʼ�����󣬱�ؿ���
	if(CloseLoop_Init()!=1){
		CloseLoopSingle.CloseLoopFlag = Open_CloseLoop;
		PRINTF_UART0("CLOOPLOOP FINISH\r\n");
		PRINTF_UART1("CLOOPLOOP FINISH\r\n");
	}
	else{
		PRINTF_UART0("OPENLOOP FINISH\r\n");
		PRINTF_UART1("OPENLOOP FINISH\r\n");
	}

	//��λ�˶�
    LimitIO_Init();
	PRINTF_UART0("LimitIO_Init\r\n");
	PRINTF_UART1("LimitIO_Init\r\n");
	io_init();
	PRINTF_UART0("io_init\r\n");
	PRINTF_UART1("io_init\r\n");
	locate_init();
	PRINTF_UART0("locate_init\r\n");
	PRINTF_UART1("locate_init\r\n");

	//
	CloseLoopUpdate();
	PRINTF_UART0("OPEN/CLOOPLOOP update\r\n");
	PRINTF_UART1("OPEN/CLOOPLOOP update\r\n");

//	LimitExit_Init();
//	PRINTF("\r\nlimit init \r\n");

	PwmTimer_Init();
	PRINTF("\r\n PWM enable \r\n");

	switch(CloseLoopSingle.CloseLoopFlag)
	{
	case Open_CloseLoop:
		PRINTF("\r\n Open Loop \r\n");
		break;
	case ADXL_CloseLoop:
		PRINTF("\r\n ADXL CloseLoop \r\n");
		break;
	case MPU_CloseLoop:
		PRINTF("\r\n MPU CloseLoop \r\n");
		break;
	}

#ifdef _DEBUG_TARM_SPEED_DELAY_TIME_
	SpeedDebugTimer_init();
#endif
}

void ReportStruct_Handle(void)
{
//	static u16 color = GREEN;
	char ReportStr[1500]="->";
	char ReportStr_Assist[200]="0";

	//1.1、处理UART1
	if(ReportStruct.Uart1ReportFlag.ExecuteFinish == 1){
		sprintf(ReportStr_Assist,"ExecuteFinish;\n");
		strcat(ReportStr, ReportStr_Assist);
		ReportStruct.Uart1ReportFlag.ExecuteFinish = 0;

		if(ReportStruct.Uart1ReportFlag.CloseLoopReport == 1){
			sprintf(ReportStr_Assist,"CloseLoop Result:\n");
			strcat(ReportStr, ReportStr_Assist);
			ReportStruct.Uart1ReportFlag.CloseLoopReport = 0;
		}
		else{
			sprintf(ReportStr_Assist,"OpenLoop Result:\n");
			strcat(ReportStr, ReportStr_Assist);
		}

		sprintf(ReportStr_Assist,"\t_&x:");
		strcat(ReportStr, ReportStr_Assist);
		memset(ReportStr_Assist, 0, sizeof(ReportStr_Assist));
		ftoa(ReportStr_Assist, g_TARM_RunRecord.pv_current.x);
		strcat(ReportStr, ReportStr_Assist);

		sprintf(ReportStr_Assist,";\t_&y:");
		strcat(ReportStr, ReportStr_Assist);
		memset(ReportStr_Assist, 0, sizeof(ReportStr_Assist));
		ftoa(ReportStr_Assist, g_TARM_RunRecord.pv_current.y);
		strcat(ReportStr, ReportStr_Assist);

		sprintf(ReportStr_Assist,";\t_&prime:");
		strcat(ReportStr, ReportStr_Assist);
		memset(ReportStr_Assist, 0, sizeof(ReportStr_Assist));
		ftoa(ReportStr_Assist, g_TARM_RunRecord.pv_current.p);
		strcat(ReportStr, ReportStr_Assist);

		sprintf(ReportStr_Assist,";\t_&vice:");
		strcat(ReportStr, ReportStr_Assist);
		memset(ReportStr_Assist, 0, sizeof(ReportStr_Assist));
		ftoa(ReportStr_Assist, g_TARM_RunRecord.pv_current.v);
		strcat(ReportStr, ReportStr_Assist);

		sprintf(ReportStr_Assist,";\r\r\n");
		strcat(ReportStr, ReportStr_Assist);

	}
	else if(ReportStruct.Uart1ReportFlag.VerifySuccess == 1){
		sprintf(ReportStr_Assist,"VerifySuccess;\n");
		strcat(ReportStr, ReportStr_Assist);
		ReportStruct.Uart1ReportFlag.VerifySuccess = 0;
	}
	else if(ReportStruct.Uart1ReportFlag.VerifyError == 1){
		sprintf(ReportStr_Assist,"VerifyError;\n");
		strcat(ReportStr, ReportStr_Assist);
		ReportStruct.Uart1ReportFlag.VerifyError = 0;
	}


	//1.2、
	if(ReportStruct.Uart1ReportFlag.CloseLoop_ErrorFlag == 1){
		sprintf(ReportStr_Assist,"LoopError;\n");
		strcat(ReportStr, ReportStr_Assist);

		PRINTF("loop error\n");
		ReportStruct.Uart1ReportFlag.CloseLoop_ErrorFlag = 0;
	}

	//1.3、上报并清空字符串
	if(strlen(ReportStr)>2)
		PRINTF("%s",ReportStr);
	memset(ReportStr, 0, sizeof(ReportStr));
	strcpy(ReportStr, "->");


	//2.1、处理串口2
	if(ReportStruct.Uart2ReportFlag.ExecuteFinish == 1){
		sprintf(ReportStr_Assist,"ExecuteFinish;\n");
		strcat(ReportStr, ReportStr_Assist);
		ReportStruct.Uart2ReportFlag.ExecuteFinish = 0;

		if(ReportStruct.Uart2ReportFlag.CloseLoopReport == 1){
			sprintf(ReportStr_Assist,"CloseLoop Result:\n");
			strcat(ReportStr, ReportStr_Assist);
			ReportStruct.Uart2ReportFlag.CloseLoopReport = 0;
		}
		else{
			sprintf(ReportStr_Assist,"OpenLoop Result:\n");
			strcat(ReportStr, ReportStr_Assist);
		}

		sprintf(ReportStr_Assist,"\t_&x:");
		strcat(ReportStr, ReportStr_Assist);
		memset(ReportStr_Assist, 0, sizeof(ReportStr_Assist));
		ftoa(ReportStr_Assist, g_TARM_RunRecord.pv_current.x);
		strcat(ReportStr, ReportStr_Assist);

		sprintf(ReportStr_Assist,";\t_&y:");
		strcat(ReportStr, ReportStr_Assist);
		memset(ReportStr_Assist, 0, sizeof(ReportStr_Assist));
		ftoa(ReportStr_Assist, g_TARM_RunRecord.pv_current.y);
		strcat(ReportStr, ReportStr_Assist);

		sprintf(ReportStr_Assist,";\t_&prime:");
		strcat(ReportStr, ReportStr_Assist);
		memset(ReportStr_Assist, 0, sizeof(ReportStr_Assist));
		ftoa(ReportStr_Assist, g_TARM_RunRecord.pv_current.p);
		strcat(ReportStr, ReportStr_Assist);

		sprintf(ReportStr_Assist,";\t_&vice:");
		strcat(ReportStr, ReportStr_Assist);
		memset(ReportStr_Assist, 0, sizeof(ReportStr_Assist));
		ftoa(ReportStr_Assist, g_TARM_RunRecord.pv_current.v);
		strcat(ReportStr, ReportStr_Assist);

		sprintf(ReportStr_Assist,";\r\r\n");
		strcat(ReportStr, ReportStr_Assist);

	}
	else if(ReportStruct.Uart2ReportFlag.VerifySuccess == 1){
		sprintf(ReportStr_Assist,"VerifySuccess;\n");
		strcat(ReportStr, ReportStr_Assist);
		ReportStruct.Uart2ReportFlag.VerifySuccess = 0;
	}
	else if(ReportStruct.Uart2ReportFlag.VerifyError == 1){
		sprintf(ReportStr_Assist,"VerifyError;\n");
		strcat(ReportStr, ReportStr_Assist);
		ReportStruct.Uart2ReportFlag.VerifyError = 0;
	}


	//2.2、
	if(ReportStruct.Uart2ReportFlag.CloseLoop_ErrorFlag == 1){
		sprintf(ReportStr_Assist,"LoopError;\n");
		strcat(ReportStr, ReportStr_Assist);

//		if(color==GREEN)
//			color = YELLOW;
//		else
//			color = GREEN;
		PRINTF_UART0("loop error\n");
//		Gui_DrawFont_GBK16(20,300,RED,color,(u8 *)"err:loop");
		ReportStruct.Uart2ReportFlag.CloseLoop_ErrorFlag = 0;
	}

	//2.3、上报\清空
//	if(strlen(ReportStr)>2)
//		esp8266_report_command(ReportStr,strlen(ReportStr));
	if(strlen(ReportStr)>2)
		PRINTF_UART1(ReportStr);
	memset(ReportStr, 0, sizeof(ReportStr));
	memset(ReportStr_Assist, 0, sizeof(ReportStr_Assist));

	//3.1、处理debug数据
#ifdef _DEBUG_TARM_SPEED_DELAY_TIME_
	if(ReportStruct.SpeedDebugStruct.ReportFlag == 1)
	{
		sprintf(ReportStr_Assist,"min speed ForTheory:%dus, min time for realy:%dus\r\n",
					ReportStruct.SpeedDebugStruct.MinTimeForTheory,
					ReportStruct.SpeedDebugStruct. MinTimeForReally);
		strcat(ReportStr, ReportStr_Assist);
		sprintf(ReportStr_Assist,"the running debug:\r\n");
		strcat(ReportStr, ReportStr_Assist);
		strcat(ReportStr, ReportStruct.SpeedDebugStruct.Buffer);
		PRINTF_UART0(ReportStr);
		PRINTF_UART0("\r\n");
		//reset
		ReportStruct.SpeedDebugStruct.MinTimeForReally=0;
		ReportStruct.SpeedDebugStruct.MinTimeForTheory=0;
		ReportStruct.SpeedDebugStruct.ReportFlag=2;
		memset(ReportStruct.SpeedDebugStruct.Buffer, 0, strlen(ReportStruct.SpeedDebugStruct.Buffer));
	}
#endif
}
